package managedbean.RawMaterialPurchase;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import merlion.common.entity.DocFile;
import merlion.common.session.stateless.FileManagerSessionLocal;
import merlion.scm.rmpm.entity.RawMaterialItemLine;
import merlion.scm.rmpm.entity.RawMaterialPurchaseOrder;
import merlion.scm.rmpm.entity.RawMaterialSalesOrder;
import merlion.scm.rmpm.entity.RawMaterialSupplyInformation;
import merlion.scm.rmpm.entity.Supplier;
import merlion.scm.rmpm.session.RawMaterialPurchaseSessionBeanLocal;
import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean(name = "rmsoManagerBean")
@ViewScoped
public class RawMaterialSalesOrderManagerBean {

    @EJB
    private RawMaterialPurchaseSessionBeanLocal rmpSessionBean;
    @EJB
    private FileManagerSessionLocal fileManager;
    private RawMaterialSalesOrder rmso;
    private RawMaterialItemLine rmil;
    private RawMaterialItemLine rmilBackup;
    private RawMaterialSalesOrder selectRmso;
    private String statusMsg;

    //--------------------------------------------------------------------------
    //                          Constructor
    //--------------------------------------------------------------------------
    public RawMaterialSalesOrderManagerBean() {

        statusMsg = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("statusMsg");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("statusMsg");
        rmso = (RawMaterialSalesOrder) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("rmso");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("rmso");

        if (rmso == null) {
            rmso = new RawMaterialSalesOrder();
            rmso.setSupplier(new Supplier());
            rmil = new RawMaterialItemLine();
        }
    }

    //--------------------------------------------------------------------------
    //                          Manager Bean Methods
    //--------------------------------------------------------------------------
    public List<RawMaterialPurchaseOrder> getAllPuchaseOrderWOSalesOrder() {
        return rmpSessionBean.getAllPurchaseOrderWOSalesOrder();
    }

    public void selectPurchaseOrder(ActionEvent event) {
        rmso.setSupplier(rmso.getRmpo().getSupplier());
    }

    public Collection<RawMaterialSupplyInformation> getSupplierRawMaterial() {
        return rmso.getSupplier().getRawMaterialsSupplied();
    }

    public void addItemLine(ActionEvent event) {

        // Validate
        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid = true;
        if (rmil.getRawMaterialSupplyInformation() == null || rmil.getRawMaterialSupplyInformation().getRawMaterial().getName().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material is required", ""));
            valid = false;
        }
        if (rmil.getQty() == 0D) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity cannot be zero", ""));
            valid = false;
        }

        ArrayList<RawMaterialItemLine> list = new ArrayList<RawMaterialItemLine>(rmso.getItemlines());
        list.remove(rmil);
        boolean materialExist = false;
        for (RawMaterialItemLine r : list) {
            if (rmil.getRawMaterialSupplyInformation().getRawMaterial().equals(r.getRawMaterialSupplyInformation().getRawMaterial())) {
                materialExist = true;
            }
        }
        if (materialExist) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw material is already in order items", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);
        if (!valid) {
            return;
        }

        rmil = rmpSessionBean.calculateLine(rmil);
        rmso.getItemlines().add(rmil);

        rmil = new RawMaterialItemLine();
    }

    public void cancelAddItemLine(ActionEvent event) {
        rmil = new RawMaterialItemLine();
    }

    public void editItemLine(ActionEvent event) {
        System.out.println("editItemLine: invoked");
        rmil = (RawMaterialItemLine) event.getComponent().getAttributes().get("selected");
        rmilBackup = rmil.clone();
    }

    public void updateItemLine(ActionEvent event) {

        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid = true;
        if (rmil.getRawMaterialSupplyInformation() == null || rmil.getRawMaterialSupplyInformation().getRawMaterial().getName().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material is required", ""));
            valid = false;
        }
        if (rmil.getQty() == 0D) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity cannot be zero", ""));
            valid = false;
        }
        if (rmil.getQty() % rmil.getRawMaterialSupplyInformation().getRawMaterial().getLotSize() != 0L) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity must be ordered in lot size", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);
        if (!valid) {
            return;
        }

        rmil = rmpSessionBean.calculateLine(rmil);
        rmil = new RawMaterialItemLine();
    }

    public void cancelEditItemLine(ActionEvent event) {
        rmil.setQty(rmilBackup.getQty());
        rmil.setRawMaterialSupplyInformation(rmilBackup.getRawMaterialSupplyInformation());
        rmil.setSubtotalSGD(rmilBackup.getSubtotalSGD());
        rmil.setSubtotalUSD(rmilBackup.getSubtotalUSD());
    }

    public void removeItemLine(ActionEvent event) {
        rmil = (RawMaterialItemLine) event.getComponent().getAttributes().get("selected");
    }

    public void confirmRemoveItemLine(ActionEvent event) {
        rmso.getItemlines().remove(rmil);
        rmil = new RawMaterialItemLine();
    }

    public void cancelRemoveItemLine(ActionEvent event) {
        rmil = new RawMaterialItemLine();
    }

    public void handleFileUploadSalesOrder(FileUploadEvent event) {

        UploadedFile file = event.getFile();
        //application code
        DocFile myDoc = new DocFile(file.getFileName(), file.getContentType(), file.getContents());
        rmso = fileManager.uploadFileIntoRawMaterialSalesOrder(myDoc, rmso);
        if (rmso != null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Supplier Invoice uploaded successfully", ""));
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Supplier Invoice upload failed", ""));
        }
    }

    public String saveSalesOrder() {

        boolean valid = true;
        if (rmso.getUploadedImage() == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sales Order File must be uploaded", ""));
            valid = false;
        }
        if (rmso.getSalesOrderId() == null || rmso.getSalesOrderId().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sales Order Id cannot be empty", ""));
            valid = false;
        }
        if (rmso.getTotal() == null || rmso.getTotal() <= 0) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Total amount is invalid", ""));
            valid = false;
        }
        if (rmso.getCurrency() == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Currency is required", ""));
            valid = false;
        }
        if (!valid) {
            return null;
        }

        // Perform purchase order matching
        if (!rmpSessionBean.matchSalesOrderItems(rmso)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Order Items in purchase order is different. Please check with supplier on the correct order items and quantities", ""));
            return null;
        }
        if (!rmpSessionBean.matchSalesOrderCurrency(rmso)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Currency in purchase order is different. Please check with supplier on currency", ""));
            return null;
        }
        if (!rmpSessionBean.matchSalesOrderTotal(rmso)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Total amount in purchase order is different. Please check with supplier on correct total amount to be paid", ""));
            return null;
        }

        rmso = rmpSessionBean.saveSalesOrder(rmso);
        if (rmso != null) {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Raw material sales order saved successfully.");
        } else {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Raw material sales order cannot be saved. Pleaase try again.");
        }
        return "storeSalesOrderStatus?faces-redirect=true";
    }

    public String viewSalesOrderDisplay() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("rmso", selectRmso);
        return "viewSalesOrderDisplay?faces-redirect=true";
    }

    public List<RawMaterialSalesOrder> getSalesOrder() {
        return rmpSessionBean.getAllSalesOrder();
    }

    //--------------------------------------------------------------------------
    //                          Getter and Setter
    //--------------------------------------------------------------------------
    public RawMaterialSalesOrder getRmso() {
        return rmso;
    }

    public void setRmso(RawMaterialSalesOrder rmso) {
        this.rmso = rmso;
    }

    public String getStatusMsg() {
        return statusMsg;
    }

    public void setStatusMsg(String statusMsg) {
        this.statusMsg = statusMsg;
    }

    public RawMaterialSalesOrder getSelectRmso() {
        return selectRmso;
    }

    public void setSelectRmso(RawMaterialSalesOrder selectRmso) {
        this.selectRmso = selectRmso;
    }

    public RawMaterialItemLine getRmil() {
        return rmil;
    }

    public void setRmil(RawMaterialItemLine rmil) {
        this.rmil = rmil;
    }

    public RawMaterialItemLine getRmilBackup() {
        return rmilBackup;
    }

    public void setRmilBackup(RawMaterialItemLine rmilBackup) {
        this.rmilBackup = rmilBackup;
    }
    
    //add by zhou hong
    public String cancelSalesOrder() {
         FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg", "Raw material sales order is cancelled.");
         System.out.println("###############################################tiao");
         return "storeSalesOrderStatus?faces-redirect=true";
    }
}
